package com.bestcem.xm.qdes.grpc.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bestcem.xm.qdes.entity.QdesProject;
import com.bestcem.xm.qdes.entity.*;
import com.bestcem.xm.qdes.grpc.v1.services.*;
import com.bestcem.xm.qdes.mapper.*;
import com.bestcem.xm.qdes.service.*;
import com.google.protobuf.StringValue;
import io.grpc.stub.StreamObserver;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.bestcem.xm.qdes.grpc.service.GrpcConstant.FAIL_STATUS;
import static com.bestcem.xm.qdes.grpc.service.GrpcConstant.SUCCESS_STATUS;

/**
 * 获取基础项目接口
 *
 * @author xiaoshu.shao <xiaoshu.shao@idiaoyan.com>
 * @version V1.0
 * @date 2022/9/21
 */
@GrpcService
@Slf4j
@RequiredArgsConstructor
public class BaseQdesGrpcService extends BaseQdesServiceGrpc.BaseQdesServiceImplBase {
    private @NonNull QdesProjectService projectService;
    private @NonNull QdesProjectEntryService projectEntryService;
    private @NonNull QdesQstructService qstructServicee;
    private @NonNull QdesQuotaService quotaService;
    private @NonNull QdesQuotaMapper qdesQuotaMapper;
    private @NonNull QdesQuestionMapper qdesQuestionMapper;
    private @NonNull com.bestcem.xm.qdes.convert.grpc.QdesGrpcConvertMapper grpcConvertMapper;
    private @NonNull QdesProjectExtraAttrMapper qdesProjectExtraAttrMapper;
    private @NonNull QdesNamelistMapper namelistMapper;
    private @NonNull QdesQstructMapper qdesQstructMapper;
    private @NonNull QdesQuestionService questionService;
    private @NonNull QdesProjectMapper projectMapper;

    @Override
    public void getQStruct(GetQStructRequest request, StreamObserver<QStructResponse> responseObserver) {
        QStructResponse.Builder result = QStructResponse.newBuilder();
        String id = request.getId();
        Objects.requireNonNull(id);
        QdesQstruct qstruct = qstructServicee.getById(id);
        if (ObjectUtils.isEmpty(qstruct)) {
            log.error(String.format("getQStruct qstruct[id=%s] not found", id));
            result.setStatus(FAIL_STATUS);
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }
        // 获取questions
        LambdaQueryWrapper<QdesQuestion> questionWrapper = Wrappers.lambdaQuery();
        questionWrapper.eq(QdesQuestion::getStructId, qstruct.getId());
        List<QdesQuestion> qdesQuestions = qdesQuestionMapper.selectList(questionWrapper);
        projectService.fillQstructData(qstruct, qdesQuestions);
        result.setStatus(SUCCESS_STATUS);
        result.setQStruct(grpcConvertMapper.toGrpcQStruct(qstruct));
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listQStruct(ListQStructRequest request, StreamObserver<QStructSearchResponse> responseObserver) {
        QStructSearchResponse.Builder result = QStructSearchResponse.newBuilder();
        QStruct old_params = request.getQStruct();
        String search = request.getSearch();
        List<Integer> status = request.getStatusList();
        List<String> fields = request.getFieldsList();
        LambdaQueryWrapper<QdesQstruct> wrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(old_params.getProjectId())) {
            wrapper.eq(QdesQstruct::getProjectId, old_params.getProjectId());
        }
        if (ObjectUtil.isNotEmpty(old_params.getVersion())) {
            wrapper.eq(QdesQstruct::getVersion, old_params.getVersion());
        }
        if (ObjectUtil.isNotEmpty(request.getVersionsList())) {
            wrapper.in(QdesQstruct::getVersion, request.getVersionsList());
        }
        /*if (ObjectUtil.isNotNull(old_params.getReleaseDt())) {
            wrapper.eq(QdesQstruct::getReleaseDt, BaseConvertMapper.googleTimestampToLocalDateTime(old_params.getReleaseDt()));
        }
        if (ObjectUtil.isNotNull(old_params.getData())) {
            wrapper.eq(QdesQstruct::getData, old_params.getData());
        }
        if (ObjectUtil.isNotNull(old_params.getWithdrawDt())) {
            wrapper.eq(QdesQstruct::getWithdrawDt, BaseConvertMapper.googleTimestampToLocalDateTime(old_params.getWithdrawDt()));
        }
        if (ObjectUtil.isNotNull(old_params.getTemplates())) {
            wrapper.eq(QdesQstruct::getTemplates, old_params.getTemplates());
        }
        if (ObjectUtil.isNotNull(old_params.getAttachments())) {
            wrapper.eq(QdesQstruct::getAttachments, old_params.getAttachments());
        }
        if (ObjectUtil.isNotNull(old_params.getCsses())) {
            wrapper.eq(QdesQstruct::getCsses, old_params.getCsses());
        }
        if (ObjectUtil.isNotNull(old_params.getUcss())) {
            wrapper.eq(QdesQstruct::getUcss, old_params.getUcss());
        }
        if (ObjectUtil.isNotNull(old_params.getScores())) {
            wrapper.eq(QdesQstruct::getScores, old_params.getScores());
        }
        if (ObjectUtil.isNotNull(old_params.getSecret())) {
            wrapper.eq(QdesQstruct::getSecretKey, old_params.getSecret());
        }
        if (ObjectUtil.isNotNull(old_params.getPolicy())) {
            wrapper.eq(QdesQstruct::getPolicy, old_params.getPolicy());
        }
        if (ObjectUtil.isNotNull(old_params.getStatus())) {
            wrapper.eq(QdesQstruct::getStatus, old_params.getStatus());
        }
        if (CollectionUtils.isEmpty(status)) {
            wrapper.in(QdesQstruct::getStatus, status);
        }*/
        //外部参数传得version集合
        List<QStruct> list = qstructServicee.list(wrapper).stream()
                .map(q -> grpcConvertMapper.toGrpcQStruct(q))
                .collect(Collectors.toList());

        result.setStatus(SUCCESS_STATUS);
        result.addAllQStructList(list);
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }


    @Override
    public void getQuota(GetQuotaRequest request, StreamObserver<QuotaResponse> responseObserver) {
        QuotaResponse.Builder result = QuotaResponse.newBuilder();
        String id = request.getId();
        Objects.requireNonNull(id);
        QdesQuota quota = quotaService.getById(id);
        if (ObjectUtils.isEmpty(quota)) {
            log.error(String.format("getQuota Quota[id=%s] not found", id));
            result.setStatus(FAIL_STATUS);
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }

        result.setStatus(SUCCESS_STATUS);
        result.setQuota(grpcConvertMapper.toGrpcQuota(quota));
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getProject(GetProjectRequest request, StreamObserver<ProjectResponse> responseObserver) {
        ProjectResponse.Builder response = ProjectResponse.newBuilder();
        String id = request.getId();
        QdesProject pro = projectService.getById(id);
        if (ObjectUtils.isEmpty(pro)) {
            log.error(String.format("getProject Project[id=%s] not found", id));
            response.setStatus(FAIL_STATUS);
            responseObserver.onNext(response.build());
            responseObserver.onCompleted();
            return;
        }

        response.setProject(grpcConvertMapper.toGrpcProject(pro));
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listProject(ListProjectRequest request, StreamObserver<ProjectSearchResponse> responseObserver) {
        Project old_params = request.getProject();
        String search = request.getSearch();
        List<Integer> status = request.getStatusList();
        List<String> fields = request.getFieldsList();
        LambdaQueryWrapper<QdesProject> projectWrapper = new LambdaQueryWrapper<>();
        /*if (ObjectUtil.isNotNull(old_params.getCode())) {
            projectWrapper.eq(QdesProject::getCode, old_params.getCode());
        }
        if (ObjectUtil.isNotNull(old_params.getTitle())) {
            projectWrapper.like(QdesProject::getTitle, old_params.getTitle());
        }
        if (ObjectUtil.isNotNull(old_params.getCreator())) {
            projectWrapper.eq(QdesProject::getCreator, old_params.getCreator());
        }*/
        if (ObjectUtil.isNotNull(old_params.getCompanyId())) {
            projectWrapper.eq(QdesProject::getCompanyId, old_params.getCompanyId());
        }
        /*if (ObjectUtil.isNotNull(old_params.getGroupListList())) {
            projectWrapper.eq(QdesProject::getGroupList, old_params.getGroupListList());
        }
        if (ObjectUtil.isNotNull(old_params.getVersion())) {
            projectWrapper.eq(QdesProject::getVersion, old_params.getVersion());
        }
        if (ObjectUtil.isNotNull(old_params.getReleaseVer())) {
            projectWrapper.eq(QdesProject::getReleaseVer, old_params.getReleaseVer());
        }*/
        if (ObjectUtil.isNotNull(old_params.getStatus())) {
            projectWrapper.eq(QdesProject::getStatus, old_params.getStatus());
        }
        if (ObjectUtil.isNotNull(request.getStatusList())) {
            projectWrapper.in(QdesProject::getStatus, request.getStatusList());
        }
        /*
        if (ObjectUtil.isNotNull(old_params.getStructId())) {
            projectWrapper.eq(QdesProject::getStructId, old_params.getStructId());
        }
        if (ObjectUtil.isNotNull(old_params.getLogicId())) {
            projectWrapper.eq(QdesProject::getLogicId, old_params.getLogicId());
        }
        if (ObjectUtil.isNotNull(old_params.getCustomAttr())) {
            projectWrapper.eq(QdesProject::getCustomAttr, old_params.getCustomAttr());
        }
        if (ObjectUtil.isNotNull(old_params.getSource())) {
            projectWrapper.eq(QdesProject::getSource, old_params.getSource());
        }
        if (ObjectUtil.isNotNull(old_params.getExtId())) {
            projectWrapper.eq(QdesProject::getExtId, old_params.getExtId());
        }
        if (ObjectUtil.isNotNull(old_params.getTimerExpire())) {
            projectWrapper.eq(QdesProject::getTimerExpire, old_params.getTimerExpire());
        }
        if (ObjectUtil.isNotNull(old_params.getPtype())) {
            projectWrapper.eq(QdesProject::getPtype, old_params.getPtype());
        }
        if (ObjectUtil.isNotNull(old_params.getIsCopyDemo())) {
            projectWrapper.eq(QdesProject::getIsCopyDemo, old_params.getIsCopyDemo());
        }
        if (CollectionUtils.isEmpty(status)) {
            projectWrapper.in(QdesProject::getStatus, status);
        }*/
        List<Project> projectList = projectService.list(projectWrapper).stream()
                .map(q -> grpcConvertMapper.toGrpcProject(q))
                .collect(Collectors.toList());

        ProjectSearchResponse.Builder response = ProjectSearchResponse.newBuilder();
        response.setStatus(SUCCESS_STATUS);
        response.addAllProjectList(projectList);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listProjectNoDefault(ListProjectRequestNoDefault request, StreamObserver<ProjectSearchResponse> responseObserver) {
        ProjectNoDefault old_params = request.getProject();
        LambdaQueryWrapper<QdesProject> projectWrapper = new LambdaQueryWrapper<>();
        //在grpcService中，可以通过getDefaultInstance的方式去判断服务调用方是没有传参数，还是传参和默认值相等
        if (!old_params.getCompanyId().equals(StringValue.getDefaultInstance())) {
            projectWrapper.eq(QdesProject::getCompanyId, old_params.getCompanyId().getValue());
        }
        if (!old_params.getTitle().equals(StringValue.getDefaultInstance())) {
            projectWrapper.like(QdesProject::getTitle, old_params.getTitle().getValue());
        }
        List<Project> projectList = projectService.list(projectWrapper).stream()
                .map(q -> grpcConvertMapper.toGrpcProject(q))
                .collect(Collectors.toList());
        ProjectSearchResponse.Builder response = ProjectSearchResponse.newBuilder();
        response.setStatus(SUCCESS_STATUS);
        response.addAllProjectList(projectList);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listProjectByIds(ListProjectByIdsRequest request, StreamObserver<ProjectSearchResponse> responseObserver) {
        ProjectSearchResponse.Builder response = ProjectSearchResponse.newBuilder();
        if (ObjectUtils.isEmpty(request.getIdsList())) {
            log.error("[qdes] listProjectByIds ids 为空");
            response.setStatus(FAIL_STATUS);
            responseObserver.onNext(response.build());
            responseObserver.onCompleted();
            return;
        }

        List<Project> projectList = projectService.listByIds(request.getIdsList()).stream()
                .map(q -> grpcConvertMapper.toGrpcProject(q))
                .collect(Collectors.toList());

        response.setStatus(SUCCESS_STATUS);
        response.addAllProjectList(projectList);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listProjectEntryByIds(ListProjectEntryByIdsRequest request, StreamObserver<ProjectEntrySearchResponse> responseObserver) {
        ProjectEntrySearchResponse.Builder response = ProjectEntrySearchResponse.newBuilder();

        if (ObjectUtils.isEmpty(request.getIdsList())) {
            log.error("[qdes] listProjectEntryByIds ids 为空");
            response.setStatus(FAIL_STATUS);
            responseObserver.onNext(response.build());
            responseObserver.onCompleted();
            return;
        }
        List<ProjectEntry> list = projectEntryService.listByIds(request.getIdsList()).stream()
                .map(q -> grpcConvertMapper.toGrpcProjectEntry(q))
                .collect(Collectors.toList());

        response.setStatus(SUCCESS_STATUS);
        response.addAllProjectEntryList(list);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listProjectEntry(ListProjectEntryRequest request, StreamObserver<ProjectEntrySearchResponse> responseObserver) {
        ProjectEntrySearchResponse.Builder response = ProjectEntrySearchResponse.newBuilder();
        LambdaQueryWrapper<QdesProjectEntry> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StrUtil.isNotBlank(request.getProjectEntry().getUserId()), QdesProjectEntry::getUserId, request.getProjectEntry().getUserId());
        queryWrapper.eq(StrUtil.isNotBlank(request.getProjectEntry().getProjectId()), QdesProjectEntry::getProjectId, request.getProjectEntry().getProjectId());
        queryWrapper.apply(CollUtil.isNotEmpty(request.getProjectEntry().getPermissionsList()), "JSON_CONTAINS(`permissions_arry`,{0})",
                JSON.toJSONString(new ArrayList<>(request.getProjectEntry().getPermissionsList())));
        List<ProjectEntry> list = projectEntryService.list(queryWrapper).stream()
                .map(q -> grpcConvertMapper.toGrpcProjectEntry(q))
                .collect(Collectors.toList());

        response.setStatus(SUCCESS_STATUS);
        response.addAllProjectEntryList(list);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    //rpc CreateProjectEntry(CreateProjectEntryRequest) returns (CreateResponse);
    @Override
    public void createProjectEntry(CreateProjectEntryRequest request, StreamObserver<CreateResponse> responseObserver) {
        CreateResponse.Builder response = CreateResponse.newBuilder();

        try {
            ProjectEntry grpcEntity = request.getProjectEntry();
            QdesProjectEntry insert = toProjectEntry(grpcEntity);
            projectEntryService.save(insert);
        } catch (Exception e) {
            log.error("createProjectEntry error", e);
            response.setStatus(FAIL_STATUS);
            responseObserver.onNext(response.build());
            responseObserver.onCompleted();
            return;
        }

        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listQuota(ListQuotaRequest request, StreamObserver<QuotaSearchResponse> responseObserver) {
        QuotaSearchResponse.Builder response = QuotaSearchResponse.newBuilder();

        LambdaQueryWrapper<QdesQuota> wrapper = new LambdaQueryWrapper<>();
        Quota quota = request.getQuota();
        wrapper.eq(StringUtils.isNotEmpty(quota.getProjectId()), QdesQuota::getProjectId, quota.getProjectId());
        wrapper.eq(QdesQuota::getQuotaType, quota.getQuotaTypeValue());
        // 这里传的status，search，field没用
        List<QdesQuota> qdesQuotas = qdesQuotaMapper.selectList(wrapper);
        List<Quota> quotas = new ArrayList<>();
        qdesQuotas.forEach(qdesQuota -> {
            Quota one = grpcConvertMapper.toGrpcQuota(qdesQuota);
            quotas.add(one);
        });
        response.addAllQuotaList(quotas);
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    // 获取单个Question
    //rpc GetQuestion(GetQuestionRequest) returns (QuestionResponse);
    @Override
    public void getQuestion(GetQuestionRequest request, StreamObserver<QuestionResponse> responseObserver) {
        QuestionResponse.Builder response = QuestionResponse.newBuilder();
        String id = request.getId();
        if (ObjectUtils.isEmpty(id)) {
            log.error("[qdes] getQuestion id 为空");
            response.setStatus(FAIL_STATUS);
            responseObserver.onNext(response.build());
            responseObserver.onCompleted();
            return;
        }
        QdesQuestion q = qdesQuestionMapper.selectById(id);
        Question one = grpcConvertMapper.toGrpcQuestion(q);
        response.setQuestion(one);
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    // 通过id批量获取Question
    //rpc ListQuestionByIds(ListQuestionByIdsRequest) returns (QuestionSearchResponse);
    @Override
    public void listQuestionByIds(ListQuestionByIdsRequest request, StreamObserver<QuestionSearchResponse> responseObserver) {
        QuestionSearchResponse.Builder response = QuestionSearchResponse.newBuilder();
        if (ObjectUtils.isEmpty(request.getIdsList())) {
            log.error("[qdes] listQuestionByIds ids 为空");
            response.setStatus(FAIL_STATUS);
            responseObserver.onNext(response.build());
            responseObserver.onCompleted();
            return;
        }
        List<Question> list = qdesQuestionMapper.selectBatchIds(request.getIdsList()).stream()
                .map(q -> grpcConvertMapper.toGrpcQuestion(q))
                .collect(Collectors.toList());

        response.addAllQuestionList(list);
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listQuestion(ListQuestionRequest request, StreamObserver<QuestionSearchResponse> responseObserver) {
        QuestionSearchResponse.Builder response = QuestionSearchResponse.newBuilder();
        Question question = request.getQuestion();
        LambdaQueryWrapper<QdesQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotEmpty(question.getStructId()), QdesQuestion::getStructId, question.getStructId());
        wrapper.eq(StringUtils.isNotEmpty(question.getExtId()), QdesQuestion::getExtId, question.getExtId());
        List<QdesQuestion> qdesQuestions = qdesQuestionMapper.selectList(wrapper);
        List<Question> questions = new ArrayList<>();
        qdesQuestions.forEach(qdesQuestion -> {
            Question one = grpcConvertMapper.toGrpcQuestion(qdesQuestion);
            questions.add(one);
        });
        response.addAllQuestionList(questions);
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void updateQuota(UpdateQuotaRequest request, StreamObserver<UpdateResponse> responseObserver) {
        UpdateResponse.Builder response = UpdateResponse.newBuilder();
        Quota quota = request.getQuota();
        String id = request.getId();
        QdesQuota qdesQuota = new QdesQuota();
        qdesQuota.setId(id);
        qdesQuota.setQuotaType(null);
        if (CollectionUtils.isNotEmpty(quota.getQuotaCondListList())) {
            qdesQuota.setQuotaCondList(JSONArray.toJSONString(quota.getQuotaCondListList()));
        }
        if (StringUtils.isNotEmpty(quota.getCol1())) {
            qdesQuota.setCol1(quota.getCol1());
        }
        if (StringUtils.isNotEmpty(quota.getCol2())) {
            qdesQuota.setCol2(quota.getCol2());
        }
        if (StringUtils.isNotEmpty(quota.getRow1())) {
            qdesQuota.setRow1(quota.getRow1());
        }
        if (StringUtils.isNotEmpty(quota.getRow2())) {
            qdesQuota.setRow2(quota.getRow2());
        }
        if (StringUtils.isNotEmpty(quota.getAvaQgidList())) {
            qdesQuota.setAvaQgidList(quota.getAvaQgidList());
        }
        if (StringUtils.isNotEmpty(quota.getName())) {
            qdesQuota.setName(quota.getName());
        }
        qdesQuotaMapper.updateById(qdesQuota);
        response.setId(id);
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listProjectExtraAttr(ListProjectExtraAttrRequest request, StreamObserver<ProjectExtraAttrSearchResponse> responseObserver) {
        ProjectExtraAttrSearchResponse.Builder response = ProjectExtraAttrSearchResponse.newBuilder();

        LambdaQueryWrapper<QdesProjectExtraAttr> wrapper = new LambdaQueryWrapper<>();
        ProjectExtraAttr projectExtraAttr = request.getProjectExtraAttr();
        if (ObjectUtil.isNotEmpty(projectExtraAttr.getId())) {
            wrapper.eq(QdesProjectExtraAttr::getId, projectExtraAttr.getId());
        }
        if (ObjectUtil.isNotEmpty(projectExtraAttr.getProjectId())) {
            wrapper.eq(QdesProjectExtraAttr::getProjectId, projectExtraAttr.getProjectId());
        }

        List<ProjectExtraAttr> projectExtraAttrList = qdesProjectExtraAttrMapper.selectList(wrapper).stream().map(q ->
                        grpcConvertMapper.toGrpcProjectExtraAttr(q))
                .collect(Collectors.toList());
        response.addAllProjectExtraAttrList(projectExtraAttrList);
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listNameList(ListNameListRequest request, StreamObserver<NameListSearchResponse> responseObserver) {
        NameListSearchResponse.Builder response = NameListSearchResponse.newBuilder();
        NameList item = request.getNameList();
        LambdaQueryWrapper<QdesNameList> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotEmpty(item.getProjectId()), QdesNameList::getProjectId, item.getProjectId());
        wrapper.eq(ObjectUtil.isNotEmpty(item.getVersion()), QdesNameList::getVersion, item.getVersion());
        wrapper.eq(ObjectUtil.isNotEmpty(item.getGid()), QdesNameList::getGid, item.getGid());

        List<QdesNameList> list = namelistMapper.selectList(wrapper);
        List<NameList> grpclist = new ArrayList<>();
        list.forEach(it -> {
            NameList one = grpcConvertMapper.toGrpcNameList(it);
            grpclist.add(one);
        });
        response.addAllNameListList(grpclist);
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void qdesListQstructWithq(QStructSearchDataResquest request, StreamObserver<QStructSearchDataResponse> responseObserver) {
        QStructSearchDataResponse.Builder response = QStructSearchDataResponse.newBuilder();
        LambdaQueryWrapper<QdesQstruct> queryWrapper = new LambdaQueryWrapper<>();
        QStruct qstruct = request.getQstruct();
        queryWrapper.eq(StrUtil.isNotEmpty(qstruct.getProjectId()), QdesQstruct::getProjectId, qstruct.getProjectId());
        queryWrapper.eq(QdesQstruct::getVersion, qstruct.getVersion());
        queryWrapper.in(CollUtil.isNotEmpty(request.getVersionList()), QdesQstruct::getVersion, request.getVersionList());
        List<QdesQstruct> qdesQstructsList = qdesQstructMapper.selectList(queryWrapper);

        List<QStruct> ret_qstruct_list = new ArrayList<>();
        qdesQstructsList.forEach(v -> {
            List<QdesQuestion> questionList = questionService.getQuestionList(v.getId(), null);
            projectService.fillQstructData(v, questionList);
            ret_qstruct_list.add(grpcConvertMapper.toGrpcQStruct(v));
        });
        response.addAllQstructList(ret_qstruct_list);
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getProjectIdList(GetProjectIdListRequest request, StreamObserver<GetProjectIdListResponse> responseObserver) {
        GetProjectIdListResponse.Builder response = GetProjectIdListResponse.newBuilder();
        String orgId = request.getOrgId();
        List<Integer> status = request.getStatusList();
        if (StringUtils.isEmpty(orgId)) {
            response.setStatus(SUCCESS_STATUS);
            responseObserver.onNext(response.build());
            responseObserver.onCompleted();
            return;
        }
        LambdaQueryWrapper<QdesProject> wrapper = new LambdaQueryWrapper<QdesProject>().eq(QdesProject::getCompanyId, orgId);
        if (CollectionUtils.isNotEmpty(status)) {
            wrapper.in(QdesProject::getStatus, new ArrayList<>(status));
        }
        wrapper.select(QdesProject::getId);
        List<QdesProject> projects = projectMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(projects)) {
            response.addAllProjectIdList(new ArrayList<>());
        } else {
            response.addAllProjectIdList(projects.stream().map(QdesProject::getId).distinct().collect(Collectors.toList()));
        }
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    @Override
    public void qdesDistinctProjectIds(QdesDistinctProjectIdsResquest request, StreamObserver<QdesDistinctProjectIdsResponse> responseObserver) {
        QdesDistinctProjectIdsResponse.Builder response = QdesDistinctProjectIdsResponse.newBuilder();
        Project project = request.getProject();
        Boolean switchLimit = JSONObject.parseObject(project.getCustomAttr()).getBoolean("switch_limit");
        LambdaQueryWrapper<QdesProject> wrapper = new LambdaQueryWrapper<>();
        if (Objects.nonNull(switchLimit)) {
            wrapper.apply("json_contains(custom_attr, '{\"switch_limit\":" + switchLimit + "}')");
        }
        List<QdesProject> projects = projectMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(projects)) {
            response.addAllProjectIdList(new ArrayList<>());
        } else {
            response.addAllProjectIdList(projects.stream().map(QdesProject::getId).distinct().collect(Collectors.toList()));
        }
        response.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(response.build());
        responseObserver.onCompleted();
    }

    private QdesProjectEntry toProjectEntry(ProjectEntry item) {
        QdesProjectEntry qdesProjectEntry = new QdesProjectEntry();
        qdesProjectEntry.setOrgId(item.getOrgId());
        qdesProjectEntry.setProjectId(item.getProjectId());
        qdesProjectEntry.setUserId(item.getUserId());
        qdesProjectEntry.setTitle(item.getTitle());
        qdesProjectEntry.setCategory(item.getCategoryValue());
        qdesProjectEntry.setPermissionsArry(JSONArray.toJSONString(item.getPermissionsList()));
        qdesProjectEntry.setPermType(item.getPermTypeValue());
        qdesProjectEntry.setFolderId(item.getFolderId());
        qdesProjectEntry.setStatus(item.getStatusValue());
        qdesProjectEntry.setBadgeStatus(item.getBadgeStatusValue());
        qdesProjectEntry.setCreatorId(item.getCreatorId());
        qdesProjectEntry.setTopOrder(item.getTopOrder());
        qdesProjectEntry.setCreatedId(item.getCreatorId());
        qdesProjectEntry.setDeleted(Boolean.FALSE);
        qdesProjectEntry.setCreatedDt(LocalDateTime.now());
        qdesProjectEntry.setUpdatedDt(LocalDateTime.now());
        return qdesProjectEntry;
    }
}